

介绍C++模板的基础概念和语言特性，通过函数模板和类模板讨论其目的和概念。再介绍其他的模板特性，比如:非类型模板参数，可变参模板，typename关键字和成员模板。并且，讨论如何处理移动语义，如何声明模板参数，以及如何使用泛型进行编译时编程。本节最后会对一些术语和模板在实际中的应用，给开发工程师和泛型库的开发者们提供一些建议。

\begin{flushleft}
\zihao{3} 为何需要模板？
\end{flushleft}

C++要求使用特定类型声明变量、函数和大多数其他类型的实体。但是，对于不同的类型，很多代码看起来一样。例如，算法快速排序的实现对于不同的数据结构(比如array<int>或vector<string>)在结构上看就是相同的，只要所包含的类型可以相互比较。

如果编程语言不支持这种泛型特性，就只有这些(糟糕的)替代方案了:

\begin{enumerate}
\item 
对不同类型重复实现相同的算法。

\item 
公共基类(比如\texttt{Object}和\texttt{void*})里面实现通用算法。

\item 
使用预处理。
\end{enumerate}

若从其它语言转投C++，可能已经使用过以上的方法了。这里来说说他们的缺点：

\begin{enumerate}
\item 
重复实现相同算法，就是重复地造轮子！并且会犯相同的错误。为了避免犯更多的错误，不会使用复杂但高效的算法。

\item 
公共基类里实现统一的代码，就等于放弃了类型检查。而且，有时候某些类必须要从特殊的基类派生出来，这会增加代码维护的成本。

\item 
采用预处理的方式，就需要实现一些“笨拙的文本替换”，这很难兼顾作用域和类型检查，更容易引发奇怪的错误。
\end{enumerate}

而模板就不会有这些问题，它就是为了一种或多种未明确定义的类型而定义的函数或者类。使用模板时，需要显式地或隐式地指定模板参数。由于模板是C++的特性，肯定会检查类型和作用域。

目前模板使用的很广，在C++标准库中，几乎所有的代码都用到了模板。标准库提供了一些针对某种特定类型的值或对象的排序算法，也提供一些数据结构(也叫容器)来维护某种特定类型的元素，对于字符串而言，“特定类型”就是“字符”。当然，这只是最基础的功能。模板还允许参数化函数或类的行为，优化代码以及参数化其他信息。这些高级特性会在后面介绍，先从简单的模板开始吧。










